import createjs from 'createjs-ts'
import { PLAYER_INIT_LENGTH, PLAYGROUND_WIDTH, PLAYGROUND_HEIGHT, ENEMY_SNAKE_NUMBER} from './Setting';
import { getRandomColor, getRandomMoveDirection } from './Util';
import Snake from './Snake';
import names from './name';
import { cloneDeep } from 'lodash';

const Point = createjs.Point;

const SNAKE_MAX_NUM = ENEMY_SNAKE_NUMBER + 1; // 同一局内最多蛇的数量

const SNAKE_UPDATE_INTERVAL = 500; // 蛇更新间隔
let snakeNames = cloneDeep(names)

/**
 * 获取Ai开始运动位置
 * @returns 
 */
const getAiSnakeStartPosition = () => {
	return new Point(Math.random()*(PLAYGROUND_WIDTH - 600)+300, Math.random()*(PLAYGROUND_HEIGHT - 600)+300)
}

export const snakesGameRanking = []
export const currentPlayer = {}
class SnakeManager{
	snakesMap = new Map()
	constructor(){
		this.gamePlayer = null
		this.gameMapLayer = null
		this.snakeCheckDelta = 0
	}

	init(gameMapLayer){
		this.gameMapLayer = gameMapLayer; // 地图实例
		// 创建玩家自身
		let startPosition = new Point(PLAYGROUND_WIDTH / 2, PLAYGROUND_HEIGHT / 2) // 开始位置
		this.gamePlayer = this.createSnake(startPosition, getRandomMoveDirection(), PLAYER_INIT_LENGTH, 'red', false, this.gameMapLayer, "player", this); //getRandomColor()
		
		let np = Math.floor(Math.random() * (snakeNames.length - ENEMY_SNAKE_NUMBER - 1)),
			inp = np;
		// 创建ai蛇
		for(let i = 0; i < ENEMY_SNAKE_NUMBER; i++){
			this.createSnake(
				getAiSnakeStartPosition(),
				getRandomMoveDirection(),
				Math.floor(Math.random()*50),
				getRandomColor(),
				true,
				this.gameMapLayer,
				snakeNames[inp++],
				this,
				Math.max(Math.floor(Math.random()*20), 5)
			);
		}
		snakeNames.splice(np, ENEMY_SNAKE_NUMBER);
		return this.gamePlayer;
	}

	getSnake(id){
		return this.snakesMap.get(id);
	}
	/**
	 * pos 玩家初始位置
	 * dir 运动方向
	 * length 蛇的长度
	 * color 蛇的颜色
	 * AI 是否是Ai
	 * stage 
	 * playerName 玩家名称
	 * @returns 
	 */
	createSnake(pos, dir, score, color, AI, stage, name, manager, pInitLength){ // pos, dir, length, color, AI, stage
		const snake = new Snake({pos, dir, score, color, AI, stage, name, manager, pInitLength})// Snake.apply(Snake, Array.prototype.slice.call(arguments));
		this.snakesMap.set(snake.snakeId, snake);
		return snake;
	}

	generateList(){
		let list = []
		for (let entity of this.snakesMap.values()) {
			// if(!entity.snakeInfo.isAi){
			// 	Object.assign(currentPlayer, entity)
			// }
			list.push({
				name: entity.snakeName,
				score: entity.score,
				killQuantity: entity.killQuantity,
				isAi: entity.snakeInfo.isAi,
			})
		}
		list.sort(function(a, b){
			return b.score - a.score
		});
		return list;
	}
	/**
	 * 更新蛇的画面
	 * @param { time stamp} updateDelta 每一帧用的时间间隔 时间戳
	 * @param {*} overCallback 回调
	 * @param {*} context 上一个调用实例
	 */
	updateSnakeMap(updateDelta, overCallback, context){
		if(!this.gamePlayer) {
			return
		}
		if(this.gamePlayer.IsDead) {
			overCallback.call(context, this.gamePlayer.score, this.gamePlayer.killQuantity)
		}
		
		for (var [id, entity] of this.snakesMap) {
			if(entity.IsDead && id !== this.gamePlayer.snakeId){
				this.snakesMap.delete(id);
				snakeNames.push(entity.snakeName);
				// ListManager(this.generateList());
				snakesGameRanking.splice(0, snakesGameRanking.length)
				snakesGameRanking.push(...this.generateList())
			}
			// 只让自己动
			// !entity.snakeInfo.isAi
			entity.updateSnake(updateDelta);
		}
		this.snakeCheckDelta += updateDelta;
		if(this.snakeCheckDelta > SNAKE_UPDATE_INTERVAL){
			this.snakeCheckDelta -= SNAKE_UPDATE_INTERVAL
			let needCreateSnakeNumber = SNAKE_MAX_NUM - this.snakesMap.size;
			// 蛇死亡后 需要重新生成新的蛇
			for(let i = 0; i < needCreateSnakeNumber; i++){
				let tIdx = Math.floor(Math.random() * (snakeNames.length-1));
				this.createSnake(
					getAiSnakeStartPosition(),
					getRandomMoveDirection(),
					Math.floor(Math.random()*24),
					getRandomColor(),
					true,
					this.gameMapLayer,
					snakeNames[tIdx],
					this,
					Math.max(Math.floor(Math.random()*20), 5)
				)
				snakeNames.splice(tIdx, 1);
			}
			snakesGameRanking.splice(0, snakesGameRanking.length)
			snakesGameRanking.push(...this.generateList())
		}
		

	}
	clear(){
		this.snakesMap = new Map();
		this.gamePlayer = null;
		this.gameMapLayer = null;
		this.snakeCheckDelta = 0;
		snakeNames = cloneDeep(names)
	}
}

export default new SnakeManager();